home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / mg2a_src.zip / EXTEND.C < prev    next >
C/C++ Source or Header  |  1991-02-16  |  21KB  |  798 lines

  1. /*
  2.  *    Extended (M-X) commands, rebinding, and 
  3.  *    startup file processing.
  4.  */
  5. #include    "def.h"
  6. #include    "kbd.h"
  7.  
  8. #ifndef NO_MACRO
  9. #include    "macro.h"
  10. #endif
  11.  
  12. #ifdef    FKEYS
  13. #include    "key.h"
  14. #ifndef    NO_STARTUP
  15. #ifndef    BINDKEY
  16. #define    BINDKEY        /* bindkey is used by FKEYS startup code */
  17. #endif
  18. #endif
  19. #endif
  20.  
  21. extern    char    *strncpy();
  22. extern    int rescan();
  23.  
  24. /* insert a string, mainly for use from macros (created by selfinsert) */
  25. /*ARGSUSED*/
  26. insert(f, n)
  27. int f, n;
  28. {
  29.     register char *cp;
  30.     char buf[128];
  31. #ifndef NO_MACRO
  32.     register int count;
  33.     int c;
  34.  
  35.     if(inmacro) {
  36.     while(--n >= 0) {
  37.         for(count = 0; count < maclcur->l_used; count++) {
  38.         if((((c=maclcur->l_text[count]) == '\n') ? lnewline()
  39.             : linsert(1, c)) != TRUE) return FALSE;
  40.         }
  41.     }
  42.     maclcur = maclcur->l_fp;
  43.     return TRUE;
  44.     }
  45.     if(n==1) thisflag |= CFINS; /* CFINS means selfinsert can tack on end */
  46. #endif
  47.     if(eread("Insert: ", buf, sizeof(buf), EFNEW) == FALSE) return FALSE;
  48.     while(--n >= 0) {
  49.     cp = buf;
  50.     while(*cp) {
  51.         if(((*cp == '\n') ? lnewline() : linsert(1, *cp)) != TRUE)
  52.         return FALSE;
  53.         cp++;
  54.     }
  55.     }
  56.     return TRUE;
  57. }
  58.  
  59. /*
  60.  * Bind a key to a function.  Cases range from the trivial (replacing an
  61.  * existing binding) to the extremly complex (creating a new prefix in a
  62.  * map_element that already has one, so the map_element must be split,
  63.  * but the keymap doesn't have enough room for another map_element, so
  64.  * the keymap is reallocated).    No attempt is made to reclaim space no
  65.  * longer used, if this is a problem flags must be added to indicate
  66.  * malloced verses static storage in both keymaps and map_elements.
  67.  * Structure assignments would come in real handy, but K&R based compilers
  68.  * don't have them.  Care is taken so running out of memory will leave
  69.  * the keymap in a usable state.
  70.  */
  71. static int remap(curmap, c, funct, pref_map)
  72. register KEYMAP    *curmap;/* pointer to the map being changed */
  73. int    c;        /* character being changed */
  74. PF    funct;        /* function being changed to */
  75. KEYMAP    *pref_map;    /* if funct==prefix, map to bind to or NULL for new */
  76. /* extern MAP_ELEMENT *ele;    must be set before calling */
  77. {
  78.     register int i;
  79.     int    n1, n2, nold;
  80.     KEYMAP    *mp;
  81.     PF    *pfp;
  82.     MAP_ELEMENT *mep;
  83.     KEYMAP *realocmap();
  84.  
  85.     if(ele >= &curmap->map_element[curmap->map_num] || c < ele->k_base) {
  86.         if(ele > &curmap->map_element[0] && (funct!=prefix ||
  87.             (ele-1)->k_prefmap==NULL)) {
  88.         n1 = c - (ele-1)->k_num;
  89.         } else n1 = HUGE;
  90.         if(ele < &curmap->map_element[curmap->map_num] && (funct!=prefix ||
  91.             ele->k_prefmap==NULL)) {
  92.         n2 = ele->k_base - c;
  93.         } else n2 = HUGE;
  94.         if(n1 <= MAPELEDEF && n1 <= n2) {
  95.         ele--;
  96.         if((pfp = (PF *)malloc((unsigned)(c - ele->k_base+1) 
  97.             * sizeof(PF))) == NULL) {
  98.             ewprintf("Out of memory");
  99.             return FALSE;
  100.         }
  101.         nold = ele->k_num - ele->k_base + 1;
  102.         for(i=0; i < nold; i++)
  103.             pfp[i] = ele->k_funcp[i];
  104.         while(--n1) pfp[i++] = curmap->map_default;
  105.         pfp[i] = funct;
  106.         ele->k_num = c;
  107.         ele->k_funcp = pfp;
  108.         } else if(n2 <= MAPELEDEF) {
  109.         if((pfp = (PF *)malloc((unsigned)(ele->k_num - c + 1) 
  110.             * sizeof(PF))) == NULL) {
  111.             ewprintf("Out of memory");
  112.             return FALSE;
  113.         }
  114.         nold = ele->k_num - ele->k_base + 1;
  115.         for(i=0; i < nold; i++)
  116.             pfp[i+n2] = ele->k_funcp[i];
  117.         while(--n2) pfp[n2] = curmap->map_default;
  118.         pfp[0] = funct;
  119.         ele->k_base = c;
  120.         ele->k_funcp = pfp;
  121.         } else {
  122.         if(curmap->map_num >= curmap->map_max &&
  123.             (curmap = realocmap(curmap)) == NULL) return FALSE;
  124.         if((pfp = (PF *)malloc(sizeof(PF))) == NULL) {
  125.             ewprintf("Out of memory");
  126.             return FALSE;
  127.         }
  128.         pfp[0] = funct;
  129.         for(mep = &curmap->map_element[curmap->map_num]; mep > ele; mep--) {
  130.             mep->k_base    = (mep-1)->k_base;
  131.             mep->k_num     = (mep-1)->k_num;
  132.             mep->k_funcp   = (mep-1)->k_funcp;
  133.             mep->k_prefmap = (mep-1)->k_prefmap;
  134.         }
  135.         ele->k_base = c;
  136.         ele->k_num = c;
  137.         ele->k_funcp = pfp;
  138.         ele->k_prefmap = NULL;
  139.         curmap->map_num++;
  140.         }
  141.         if(funct == prefix) {
  142.         if(pref_map != NULL) {
  143.             ele->k_prefmap = pref_map;
  144.         } else {
  145.             if((mp = (KEYMAP *)malloc(sizeof(KEYMAP) +
  146.                 (MAPINIT-1)*sizeof(MAP_ELEMENT))) == NULL) {
  147.             ewprintf("Out of memory");
  148.             ele->k_funcp[c - ele->k_base] = curmap->map_default;
  149.             return FALSE;
  150.             }
  151.             mp->map_num = 0;
  152.             mp->map_max = MAPINIT;
  153.             mp->map_default = rescan;
  154.             ele->k_prefmap = mp;
  155.         }
  156.         }
  157.     } else {
  158.         n1 = c - ele->k_base;
  159.         if(ele->k_funcp[n1] == funct && (funct!=prefix || pref_map==NULL ||
  160.             pref_map==ele->k_prefmap))
  161.         return TRUE;    /* no change */
  162.         if(funct!=prefix || ele->k_prefmap==NULL) {
  163.         if(ele->k_funcp[n1] == prefix)
  164.             ele->k_prefmap = (KEYMAP *)NULL;
  165.         ele->k_funcp[n1] = funct;    /* easy case */
  166.         if(funct==prefix) {
  167.             if(pref_map!=NULL)
  168.             ele->k_prefmap = pref_map;
  169.             else {
  170.             if((mp = (KEYMAP *)malloc(sizeof(KEYMAP) +
  171.                 (MAPINIT-1)*sizeof(MAP_ELEMENT))) == NULL) {
  172.                 ewprintf("Out of memory");
  173.                 ele->k_funcp[c - ele->k_base] = curmap->map_default;
  174.                 return FALSE;
  175.             }
  176.             mp->map_num = 0;
  177.             mp->map_max = MAPINIT;
  178.             mp->map_default = rescan;
  179.             ele->k_prefmap = mp;
  180.             }
  181.         }
  182.         } else {
  183.         /* this case is the splits */
  184.         /* determine which side of the break c goes on */
  185.         /* 0 = after break; 1 = before break */
  186.         n2 = 1;
  187.         for(i=0; n2 && i < n1; i++)
  188.             n2 &= ele->k_funcp[i] != prefix;
  189.         if(curmap->map_num >= curmap->map_max &&
  190.             (curmap = realocmap(curmap)) == NULL) return FALSE;
  191.         if((pfp = (PF *)malloc((unsigned)(ele->k_num - c + !n2) 
  192.             * sizeof(PF))) == NULL) {
  193.             ewprintf("Out of memory");
  194.             return FALSE;
  195.         }
  196.         ele->k_funcp[n1] = prefix;
  197.         for(i=n1+n2; i <= ele->k_num - ele->k_base; i++)
  198.             pfp[i-n1-n2] = ele->k_funcp[i];
  199.         for(mep = &curmap->map_element[curmap->map_num]; mep > ele; mep--) {
  200.             mep->k_base    = (mep-1)->k_base;
  201.             mep->k_num     = (mep-1)->k_num;
  202.             mep->k_funcp   = (mep-1)->k_funcp;
  203.             mep->k_prefmap = (mep-1)->k_prefmap;
  204.         }
  205.         ele->k_num = c - !n2;
  206.         (ele+1)->k_base = c + n2;
  207.         (ele+1)->k_funcp = pfp;
  208.         ele += !n2;
  209.         ele->k_prefmap = NULL;
  210.         curmap->map_num++;
  211.         if(pref_map == NULL) {
  212.             if((mp = (KEYMAP *)malloc(sizeof(KEYMAP) +
  213.                 (MAPINIT-1)*sizeof(MAP_ELEMENT))) == NULL) {
  214.             ewprintf("Out of memory");
  215.             ele->k_funcp[c - ele->k_base] = curmap->map_default;
  216.             return FALSE;
  217.             }
  218.             mp->map_num = 0;
  219.             mp->map_max = MAPINIT;
  220.             mp->map_default = rescan;
  221.             ele->k_prefmap = mp;
  222.         } else ele->k_prefmap = pref_map;
  223.         }
  224.     }
  225.     return TRUE;
  226. }
  227.  
  228. /* reallocate a keymap, used above */
  229. static KEYMAP *realocmap(curmap)
  230. register KEYMAP *curmap;
  231. {
  232.     register KEYMAP *mp;
  233.     register int i;
  234.     VOID fixmap();
  235.     extern int nmaps;
  236.  
  237.     if((mp = (KEYMAP *)malloc((unsigned)(sizeof(KEYMAP)+
  238.         (curmap->map_max+(MAPGROW-1))*sizeof(MAP_ELEMENT)))) == NULL) {
  239.     ewprintf("Out of memory");
  240.     return NULL;
  241.     }
  242.     mp->map_num = curmap->map_num;
  243.     mp->map_max = curmap->map_max + MAPGROW;
  244.     mp->map_default = curmap->map_default;
  245.     for(i=curmap->map_num; i--; ) {
  246.     mp->map_element[i].k_base    = curmap->map_element[i].k_base;
  247.     mp->map_element[i].k_num    = curmap->map_element[i].k_num;
  248.     mp->map_element[i].k_funcp    = curmap->map_element[i].k_funcp;
  249.     mp->map_element[i].k_prefmap    = curmap->map_element[i].k_prefmap;
  250.     }
  251.     for(i=nmaps; i--; ) {
  252.     if(map_table[i].p_map == curmap) map_table[i].p_map = mp;
  253.     else fixmap(curmap, mp, map_table[i].p_map);
  254.     }
  255.     ele = &mp->map_element[ele - &curmap->map_element[0]];
  256.     return mp;
  257. }
  258.  
  259. /* fix references to a reallocated keymap (recursive) */
  260. static VOID fixmap(curmap, mp, mt)
  261. register KEYMAP *mt;
  262. register KEYMAP *curmap;
  263. KEYMAP *mp;
  264. {
  265.     register int i;
  266.  
  267.     for(i = mt->map_num; i--; ) {
  268.     if(mt->map_element[i].k_prefmap != NULL) {
  269.         if(mt->map_element[i].k_prefmap == curmap)
  270.             mt->map_element[i].k_prefmap = mp;
  271.         else fixmap(curmap, mp, mt->map_element[i].k_prefmap);
  272.     }
  273.     }
  274. }
  275.  
  276. /*
  277.  *